package com.utooo.util;


import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @Description: 获取编号
 * @Author SJD
 * @Date: 2025/4/28 15:32
 * @Copyright: 南京优通信息科技股份有限公司
 */
@Component
public final class GenerateReceiptNo {

    private static final Map<String, String> receiptNoMap = new ConcurrentHashMap<>();

    /**
     * 获取各个表字段编号
     *
     * @param prefix    前缀
     * @param fieldName 编号表字段
     * @param mapper    表mapper
     * @param <T>
     * @return 编号
     */
    public static <T> String getGenerateReceiptNo(String prefix, String fieldName, BaseMapper<T> mapper) {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        String datePart = currentDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        // 生成序列号
        int maxSequence = 0;
        String key = prefix + fieldName + datePart;
        if (receiptNoMap.containsKey(key)) {
            maxSequence = Integer.parseInt(receiptNoMap.get(key)
                    .substring((prefix + datePart).length()));
        } else {
            // 查询当天已有的最大订单号
            QueryWrapper<T> queryWrapper = new QueryWrapper<>();
            queryWrapper.likeRight(fieldName, prefix + datePart);
            queryWrapper.orderByDesc(fieldName);
            queryWrapper.last("LIMIT 1");
            // 使用传入的 Mapper 查询
            T entity = mapper.selectOne(queryWrapper);
            if (entity != null) {
                String receiptNo = getFieldValue(entity, fieldName);
                maxSequence = Integer.parseInt(receiptNo.substring((prefix + datePart).length()));
            }
        }
        int nextSequence = maxSequence + 1;
        String sequencePart = String.format("%03d", nextSequence);
        String receiptNo = prefix + datePart + sequencePart;
        receiptNoMap.put(key, receiptNo);
        return receiptNo;
    }

    private static <T> String getFieldValue(T entity, String fieldName) {
        try {
            // 获取实体类的所有字段
            Field[] fields = entity.getClass().getDeclaredFields();
            for (Field field : fields) {
                // 检查字段是否有@TableField注解
                TableField tableField = field.getAnnotation(TableField.class);
                if (tableField != null && fieldName.equals(tableField.value())) {
                    field.setAccessible(true);
                    return (String) field.get(entity);
                }
            }
            throw new NoSuchFieldException("Field not found: " + fieldName);
        } catch (Exception e) {
            throw new RuntimeException("Failed to get field value", e);
        }
    }

}
